package com.ylb.rent.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sun.org.apache.xpath.internal.operations.Or;
import com.ylb.rent.config.RabbitMQConfig;
import com.ylb.rent.constant.OrderConstant;
import com.ylb.rent.constant.ResponseCode;
import com.ylb.rent.dao.OrderMapper;
import com.ylb.rent.entity.Order;
import com.ylb.rent.entity.dto.RoomOrderDto;
import com.ylb.rent.entity.vo.OrderVo;
import com.ylb.rent.exception.BusinessException;
import com.ylb.rent.service.IOrderService;
import com.ylb.rent.util.R;
import com.ylb.rent.util.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @AUTHOR:游李滨
 * @DATE:2023/7/5 10:01
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    TokenUtil tokenUtil;


//    订单失效期: 单位ms
    int orderExpire=1000*60*10;



    @Override
    public List<OrderVo> all() {

        List<Order> orderList = this.baseMapper.selectList(new QueryWrapper<>());
        return orderList.stream().map(i -> {
//            TODO 还需要查出用户的昵称
            return new OrderVo(i);
        }).collect(Collectors.toList());
    }

    @Override
    public List<OrderVo> list(Order order) {
//        TODO 需要查出用户昵称


        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();


        List<Order> orders = this.baseMapper.selectList(orderQueryWrapper);
        return orders.stream().map(OrderVo::new).collect(Collectors.toList());

    }

    @Override
    public int update(Order order) {
        if (order.getId() == 0){
            return 0;
        }
        return this.baseMapper.updateById(order);
    }

    private void initInsertOrder(Order order) throws BusinessException {



//        设置订单编号
        String uuid = IdUtil.createSnowflake(1, 1).nextIdStr();
        order.setOrderNo(uuid);
//        设置订单状态
        order.setStatus(OrderConstant.STATUS_WAIT);
//        设置用户id
        long userId = tokenUtil.getUserId();
        if(userId < 1){
            throw new BusinessException(ResponseCode.NOT_AUTH,"未登录");
        }
        order.setUserId(userId);

//        填充时间
        Date date = new Date();
        Timestamp timestamp = new Timestamp(date.getTime());
        order.setCreateTime(timestamp);
        order.setUpdateTime(timestamp);
//
    }
    /**
     *
     *  正常返回雪花id，不正常返回null
     *
     * @param orderDto*/
    @Override
    public Order insertOrder(RoomOrderDto orderDto) throws BusinessException {


        Order order = new Order();
        this.initInsertOrder(order);
        //        设置开始时间和结束时间
        order.setFromDate(orderDto.getFromDate());
        order.setToDate(orderDto.getToDate());

//        TODO 检查用户租期是否合法


//        TODO 计算用户总计租金，这里设一个测试值
        order.setTotalAmount(100);


//        加入数据库
        int insert = this.baseMapper.insert(order);


        if(insert==0){
            return null;
        }

        return order;
    }

    @Override
    public Order selectOrderByOrderNo(String orderNo) {
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        wrapper.eq("order_no",orderNo);
        return this.baseMapper.selectOne(wrapper);
    }

    @Override
    public boolean payOk(String orderNo) {
        Order o = this.selectOrderByOrderNo(orderNo);
        if(ObjectUtil.isEmpty(o)){
            log.error("[支付成功] 修改订单状态 -- 失败 ，原因:查询不到该订单[{}]",orderNo);
            return false;
        }
        if( o.getStatus() == OrderConstant.STATUS_WAIT){
            Order order = Order.builder().orderNo(orderNo).status(OrderConstant.STATUS_OK).build();
            UpdateWrapper<Order> wrapper = new UpdateWrapper<>();
            wrapper.eq("order_no",orderNo);

            boolean result=this.baseMapper.update(order,wrapper) == 1;
            log.error("[支付成功] 修改订单状态 -- {}",result);
            return result;
        }
        log.error("[支付成功] 修改订单状态 -- 失败 ，原因:订单已被取消");
        return false;



    }

    @Override
    public boolean payCancel(String orderNo) {
        Order order = Order.builder().orderNo(orderNo).status(OrderConstant.STATUS_CANCEL).build();
        UpdateWrapper<Order> wrapper = new UpdateWrapper<>();
        wrapper.eq("order_no",orderNo);
        return this.baseMapper.update(order,wrapper)==1;
    }

    public void sendCancelMessage(String orderNo){
        //        创建取消支付消息
        String dtExchangeName = RabbitMQConfig.ORDER_EXCHANGE_NAME;
        String routeKey = RabbitMQConfig.ORDER_ROUTE_KEY;
        log.error("[发送取消订单消息] orderNo -- {}",orderNo);
        rabbitTemplate.convertAndSend(dtExchangeName,routeKey,orderNo,messagePostProcessor());
    }

    //处理待发送消息
    private MessagePostProcessor messagePostProcessor(){
        return  new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                //设置有效期
                message.getMessageProperties().setExpiration(String.valueOf(orderExpire));
                return message;
            }
        };
    }

}
